/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rc;

import java.io.IOException;
import java.net.SocketException;
import tal.drivechain.plugin.Channel;
import tal.drivechain.plugin.Module;
import tal.drivechain.variable.Variable;
import tal.drivechain.variable.types.DataType;
import tal.remotecanvas.CanvasEventServer;
import tal.remotecanvas.CanvasMessageServer;
import tal.remotecanvas.CanvasPacket;
import tal.remotecanvas.RawPacketListener;

/**
 *
 * @author Tal Eisenberg
 */
public class Server extends Module implements RawPacketListener {
    private CanvasEventServer eventServer;
    private CanvasMessageServer messageServer;

    String host = null;
    int outport = -1 ;
    int inport = -1;

    public Server() {
        eventServer = new CanvasEventServer();
        eventServer.setRawPacketListener(this);
        eventServer.debug = false;
        try {
            messageServer = new CanvasMessageServer();
            messageServer.debug = false;
        } catch (IOException e) { log("While initializing canvas message server: " + e, MSG.ERROR); }        
    }

    @Override
    protected void msgReceived(Variable in, long timestamp, Channel channel) {
        if (channel!=channel.CHAIN) return;
        
        if (in.getDataType().matches(DataType.VAR)) {
            CanvasPacket packet = (CanvasPacket)in.getInternalValue();
            try {
                messageServer.sendCanvasPacket(packet);
                if (debugFlag) log("Sent " + packet.toString() + " to " + host + ":" + outport, MSG.DEBUG);
            } catch (IOException ex) {
                log("while sending packet: " + ex, MSG.ERROR);
            }
        } else {
            if (debugFlag) log("Received a message of invalid type " + in.getDataType().getName() + ". Expecting int[]", MSG.DEBUG);
        }
    }

    public void setHost(String host) {
        if (this.host!=null && this.host.equals(host)) return;
        this.host = host;
        setOutAddress();
    } public String getHost() { return host; }

    public void setOutPort(Integer outport) {
        if (this.outport == outport) return;

        this.outport = outport;
        setOutAddress();
    } public int getOutPort() { return outport; }

    public void setInPort(Integer inport) {
        if (this.inport == inport) return;

        this.inport = inport;
        if (isRunning()) { stop(); start(); }
    } public int getInPort() { return inport; }

    @Override
    public void setDebugFlag(boolean debugFlag) {
        super.setDebugFlag(debugFlag);
        eventServer.debug = debugFlag;
        //messageServer.debug = debugFlag;
    }

    @Override
    public void start() {
        if (isRunning()) return;

        super.start();
        try {
            eventServer.listenOnPort(inport);
        } catch (SocketException ex) {
            log("listenon: " + ex, MSG.ERROR);
        }
    }

    @Override
    public void stop() {
        if (!isRunning()) return;
        
        super.stop();
        eventServer.closeConnection();
        log("Stopped listening on port " + inport, MSG.INFO);

    }

    private void setOutAddress() {
        System.out.println("host==" + host + " outport==" + outport);
        if (host==null || outport == -1)
            return;

        messageServer.setAddress(host, outport);
        log("Setting outgoing address: " + host + ":" + outport,MSG.ANOUNCE);
    }

    public void receivedPacket(CanvasPacket packet) {
        Variable varPacket = new Variable(packet.eventId.name(), DataType.VAR, packet, true);
        this.sendToOutputs(varPacket, -1);
    }
}
